/**
 * Copyright (C) @2014 Webank Group Holding Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.webank.framework.dto;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import cn.webank.rmb.api.Util;
import cn.webank.rmb.destination.Destination;
import cn.webank.rmb.destination.SimpleDestination;
import cn.webank.rmb.message.AppHeader;
import cn.webank.rmb.message.Ret;
import cn.webank.rmb.message.SysHeader;

/**
 * 同步消息类
 * 
 * @author jonyang
 *
 * @param <E>
 *            业务请求对象类型
 * @param <T>
 *            业务返回对象类型
 */
abstract public class SyncRMBMessage<E, T> extends BaseRMBMessage<E> {

	public final static String SYS_EXCEPTION = "10000";
	public final static String SYS_EXCEPTION_MSG = "系统异常,请稍后重试";
	

	protected Class<T> responseObjectClass;

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.webank.framework.dto.BaseRMBMessage#getDestination()
	 */
	@Override
	public Destination createDestination() {
		return new SimpleDestination(WEBANK_CORPORATION_ID,null, null, null);
	}

	/**
	 * @return the responseObjectClass
	 */
	public Class<T> getResponseObjectClass() {
		return responseObjectClass;
	}

	@SuppressWarnings("unchecked")
	protected SyncRMBMessage() {
		super();
		this.rmbMessage = Util.createMessage(new SysHeader(), new AppHeader(),
				createDestination(), null);
		this.responseObjectClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[1];
	}

	/**
	 * @return the responseObject
	 */
	public T getResponseObject() {
		String content = this.rmbMessage.getContent();
		if (content == null)
			return null;

		return jsonMapper.fromJson(content, responseObjectClass);

	}

	/**
	 * @param responseObject
	 *            the responseObject to set
	 */
	public void setResponseObject(T responseObject) {
		if (responseObject == null) {
			this.rmbMessage.setContent(null);
		} else {
			this.rmbMessage.setContent(jsonMapper.toJson(responseObject));
		}
	}

	/**
	 * 处理rmb返回消息
	 * 
	 * @param message
	 *            rmb消息
	 * @param bizErrors
	 *            业务异常
	 * @param <E> 同步调用输入参数类型
	 * @param <T> 同步调用输出参数类型          
	 * @return true rmb调用成功，false rmb调用失败
	 */
	public static <E, T> boolean handleRmbMessageResponse(
			SyncRMBMessage<E, T> message, BizErrors bizErrors) {
		Assert.notNull(message, "rmb response message must not be null");
		Assert.notNull(bizErrors, "bizErrors must not be null");
		
		if (message.getRetStatus() == null) {
			bizErrors.reject(SYS_EXCEPTION, null, SYS_EXCEPTION_MSG);
			return false;
		}

		if (message.getRetStatus().equalsIgnoreCase(
				AppHeader.RET_STATUS_FAILURE)) {
			List<Ret> retList = message.getRetList();
			if (CollectionUtils.isEmpty(retList)) {
				bizErrors.reject(SYS_EXCEPTION, null, SYS_EXCEPTION_MSG);
			} else {
				for (Ret r : retList) {
					bizErrors.reject(r.getCode(), null, r.getMsg());
				}
			}

			return false;
		}

		return true;
	}

}
